using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Drawing;

namespace UIDesigner
{
  class CtrlSrcMaker
  {

    public static string OutWinProc(SortedControls cc)
    {
      int id;
      string str = "";
      str +=
@"
#pragma comment(linker, ""/manifestdependency:\""type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='x86' publicKeyToken='6595b64144ccf1df' language='*'\"""")

#include <Windows.h>

#include ""Utility.h""

";
      id = オプション.StartID;
      foreach (Control c in cc)
      {
        str += "const int " + IdString(c) + " = " + id + "; \r\n";
        id++;
        if (c is GroupBox)
        {
          foreach (Control cOnGroup in c.Controls)
          {
            str += "const int " + IdString(cOnGroup) + " = " + id + "; \r\n";
          }
        }
      }
      str += "\r\n\r\n" + EditStructString(cc);
      str +=
@"
HINSTANCE hInst;

LRESULT CALLBACK WinProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
" + AllDefinitionString(cc) +
@"
  switch (message) {
  case WM_CREATE:
" + OutCode(cc);
      str += @"
    return 0;
"
      + WM_COMMANDString(cc) +
@"
  case WM_DESTROY:
    PostQuitMessage(0);
    return 0;
  }
  return DefWindowProc(hWnd, message, wParam, lParam);
}
";
      return str + EditStructSubstitutionString(cc);
    }
    public static string OutCode(SortedControls cc)
    {
      string str = "";
      foreach (Control c in cc)
      {
        str += CreateWindowAndSetFontString(c, "hWnd");
        if (c is GroupBox)
        {
          GroupBox gb = (GroupBox)c;
          foreach (Control cOnGroup in gb.Controls)
          {
            str += CreateWindowAndSetFontString(cOnGroup, gb.Name);
          }
        }
      }
      return str;
    }
    private static string CreateWindowAndSetFontString(Control c, string parent)
    {
      string str = "    " + c.Name + " = CreateWindowA(" +
          "\"" + ControlString(c) + "\", " +
          "\"" + c.Text + "\", " +
          StyleString(c) + ", " +
          c.Left + ", " +
          c.Top + ", " +
          (c.Right - c.Left + 1) + ", " +
          (c.Bottom - c.Top + 1) + ", " +
          parent + ", ";
      if (c is Label)
      {
        str += "NULL";
      }
      else
      {
        str += "(HMENU)" + IdString(c);
      }
      str += ", hInst, NULL);\r\n";
      str += "    SendMessage(" + c.Name + ",WM_SETFONT,(WPARAM)" + "GetFont(" + FontParameterString(c) + "), MAKELPARAM(TRUE, 0));\r\n";
      return str;
    }
    private static string FontParameterString(Control c)
    {
      Font f = c.Font;
      return "\"" + f.Name + "\", " + f.SizeInPoints + ", " + f.Bold.ToString().ToLower() + ", "
        + f.Italic.ToString().ToLower() + ", " + f.Underline.ToString().ToLower() + ", " + f.Strikeout.ToString().ToLower();
    }
    public static string ControlString(Control c)
    {
      if (c is Button) return "BUTTON";
      if (c is CheckBox) return "BUTTON"; // BS_CHECKBOX 指定が必要
      if (c is ComboBox) return "COMBOBOX";
      if (c is GroupBox) return "BUTTON"; // BS_GROUPBOX 指定が必要
      if (c is Label) return "STATIC";
      if (c is ListBox) return "LISTBOX";
      if (c is MdiClient) return "MDICLIENT";
      if (c is RadioButton) return "BUTTON"; // BS_AUTORADIOBUTTON 指定が必要
      if (c is RichTextBox) return "RICHEDIT_CLASS";
      if (c is ScrollBar) return "SCROLLBAR";
      if (c is TextBox) return "EDIT";
      return "不明";
    }
    //コントロールID文字列
    private static string IdString(Control c)
    {
      return Converter.IDConst("ID_" + c.Name.ToUpper());
    }
    //定義文字列すべて
    private static string AllDefinitionString(SortedControls cc)
    {
      string str = "";
      if (cc.Has<Button>()) str += DefinitionString<Button>(cc);
      if (cc.Has<CheckBox>()) str += DefinitionString<CheckBox>(cc);
      if (cc.Has<ComboBox>()) str += DefinitionString<ComboBox>(cc);
      if (cc.Has<GroupBox>())
      {
        str += DefinitionString<GroupBox>(cc);
        str += DefinitionOnGroupBoxString(cc);
      }
      if (cc.Has<Label>()) str += DefinitionString<Label>(cc);
      if (cc.Has<ListBox>()) str += DefinitionString<ListBox>(cc);
      if (cc.Has<RadioButton>()) str += DefinitionString<RadioButton>(cc);
      if (cc.Has<RichTextBox>()) str += DefinitionString<RichTextBox>(cc);
      if (cc.Has<ScrollBar>()) str += DefinitionString<ScrollBar>(cc);
      if (cc.Has<TextBox>()) str += DefinitionString<TextBox>(cc);
      return str;
    }
    //定義文字列
    private static string DefinitionString<T>(SortedControls cc)
    {
      string str = "  static HWND ";
      bool is_first = true;
      foreach (Control c in cc)
      {
        if (c is T)
        {
          if (is_first)
          {
            is_first = false;
          }
          else
          {
            str += ", ";
          }
          str += c.Name;
        }
      }
      return str + ";\r\n";
    }
    private static string DefinitionOnGroupBoxString(SortedControls cc)
    {
      string str = "  static HWND ";
      foreach (Control c in cc)
      {
        if (c is GroupBox)
        {
          bool is_first = true;
          foreach (Control cOnGroup in c.Controls)
          {
            if (is_first)
            {
              is_first = false;
            }
            else
            {
              str += ", ";
            }
            str += cOnGroup.Name;
          }
          str += ";\r\n";
        }
      }
      return str;
    }
    //UIデータ用構造体
    private static string EditStructString(SortedControls cc)
    {
      string str = "const int " + Converter.Const("MAX_EDIT_SIZE") + " = 256;\r\n\r\n";
      str += "struct UIData{\r\n";
      foreach (Control c in cc)
      {
        if (c is TextBox)
        {
          str += "  char " + c.Name + "[" + Converter.Const("MAX_EDIT_SIZE") + "];\r\n";
        }
      }
      return str + "};\r\n";
    }
    //UIData構造体への代入用コード
    private static string EditStructSubstitutionString(SortedControls cc)
    {
      //      GetWindowTextA(text_bad1, &edits_data.text_bad1, kMaxEditSize);
      string str = "\r\n/* UIData構造体への代入用コード\r\n";
      foreach (System.Windows.Forms.Control c in cc)
      {
        if (c is TextBox)
        {
          str += "      GetWindowTextA(" + c.Name + ", &edits_data." + c.Name + ", kMaxEditSize);\r\n";
        }
      }
      return str + "*/\r\n";
    }
    //ボタンを押した時用のWM_COMMANDコード
    private static string WM_COMMANDString(SortedControls cc)
    {
      string str =
      @"
  case WM_COMMAND:
    switch( LOWORD(wParam) ){
";
      foreach (Control c in cc)
      {
        if (c is Button)
        {
          str += "    case " + IdString(c) + ": // [" + c.Text + "]ボタン\r\n      return 0;\r\n";
        }
      }
      return str + "    }\r\n    break;";
    }
    //コントロールスタイル文字列
    private static string StyleString(Control c)
    {
      string str = "";
      if (c is Button)
      {
        Button button = (Button)c;
        str = "WS_CHILD|WS_VISIBLE";
        if (button.TabStop) str += "|WS_TABSTOP";
        return str;
      }
      if (c is CheckBox)
      {
        CheckBox cb = (CheckBox)c;
        str = "WS_CHILD|WS_VISIBLE"; // BS_CHECKBOX
        if (cb.TabStop) str += "|WS_TABSTOP";
        if (cb.ThreeState) str += "|BS_AUTO3STATE";
        else str += "|BS_AUTOCHECKBOX";
        ContentAlignment ca = cb.CheckAlign;
        if (ca == ContentAlignment.BottomRight || ca == ContentAlignment.MiddleRight || ca == ContentAlignment.TopRight)
          str += "|BS_RIGHTBUTTON"; // BS_RIGHTBUTTON は BS_LEFTTEXT と等しい(WinUser.h)
        return str;
      }
      if (c is ComboBox)
      {
        ComboBox cb = (ComboBox)c;
        str = "WS_CHILD|WS_VISIBLE";
        if (cb.TabStop) str += "|WS_TABSTOP";
        switch (cb.DropDownStyle)
        {
          case ComboBoxStyle.Simple:
            str += "|CBS_SIMPLE ";
            break;
          case ComboBoxStyle.DropDown:
            str += "|CBS_DROPDOWN";
            break;
          case ComboBoxStyle.DropDownList:
            str += "|CBS_DROPDOWNLIST";
            break;
        }
        if (cb.Sorted) str += "|CBS_SORT";
        return str;
      }
      if (c is GroupBox)
      {
        GroupBox gb = (GroupBox)c;
        str = "WS_CHILD|WS_VISIBLE|BS_GROUPBOX";
        if (gb.TabStop) str += "|WS_TABSTOP";
        return str;
      }
      if (c is Label)
      {
        Label label = (Label)c;
        str = "WS_CHILD|WS_VISIBLE";
        return str;
      }
      if (c is ListBox)
      {
        ListBox lb = (ListBox)c;
        str = "WS_CHILD|WS_VISIBLE|WS_BORDER|WS_VSCROLL|LBS_NOTIFY";
        if (lb.TabStop) str += "|WS_TABSTOP";
        if (lb.Sorted) str += "|LBS_SORT";
        return str;
      }
      if (c is MdiClient)
      {
        MdiClient mc = (MdiClient)c;
        str = "WS_CHILD|WS_VISIBLE";
        return str;
      }
      if (c is RadioButton)
      {
        RadioButton rb = (RadioButton)c;
        str = "WS_CHILD|WS_VISIBLE|BS_AUTORADIOBUTTON";
        if (rb.TabStop) str += "|WS_TABSTOP";
        return str;
      }
      if (c is RichTextBox)
      {
        RichTextBox rtb = (RichTextBox)c;
        str = "WS_CHILD|WS_VISIBLE";
        if (rtb.TabStop) str += "|WS_TABSTOP";
        return str;
      }
      if (c is ScrollBar)
      {
        ScrollBar sb = (ScrollBar)c;
        str = "WS_CHILD|WS_VISIBLE";
        if (sb is HScrollBar) str += "|WS_HSCROLL";
        if (sb is VScrollBar) str += "|WS_VSCROLL";
        return str;
      }
      if (c is TextBox)
      {
        TextBox tb = (TextBox)c;
        str = "WS_CHILD|WS_VISIBLE|WS_BORDER";
        //if (tb.BorderStyle == BorderStyle.FixedSingle) str += "|WS_BORDER";
        //if (tb.BorderStyle == BorderStyle.Fixed3D) str += "|WS_DLGFRAME";//不明
        if (tb.TabStop) str += "|WS_TABSTOP";
        switch (tb.ScrollBars)
        {
          case ScrollBars.Horizontal:
            str += "|WS_HSCROLL";
            break;
          case ScrollBars.Vertical:
            str += "|WS_VSCROLL";
            break;
          case ScrollBars.Both:
            str += "|WS_HSCROLL|WS_VSCROLL";
            break;
        }
        return str + (tb.Multiline ? "|ES_MULTILINE|ES_WANTRETURN" : "") + (tb.WordWrap ? "" : "|ES_AUTOHSCROLL");
      }
      return "WS_CHILD | WS_VISIBLE";
    }
  }
}
